<template>
  <div class="websocket-session-demo">
    <h2>WebSocket 连接与 SessionId 获取</h2>

    <div class="connection-info">
      <div class="status" :class="connectionStatus">
        连接状态: {{ statusText }}
      </div>
      <div v-if="sessionId" class="session-id">
        会话 ID: <code>{{ sessionId }}</code>
      </div>
    </div>

    <div class="controls">
      <el-input
        v-model="wsUrl"
        placeholder="WebSocket 地址 (如 ws://localhost:8080)"
        class="url-input"
      />
      <el-button
        @click="toggleConnection"
        :loading="isConnecting"
        :type="isConnected ? 'danger' : 'primary'"
      >
        {{ isConnected ? '断开连接' : '连接' }}
      </el-button>
    </div>

    <div class="message-log">
      <h3>消息日志</h3>
      <div class="log-entry" v-for="(log, index) in messageLogs" :key="index">
        <span class="log-time">{{ log.time }}</span>
        <span class="log-content" :class="log.type">{{ log.content }}</span>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onUnmounted, nextTick } from 'vue';
import { ElInput, ElButton } from 'element-plus';

// 状态管理
const wsUrl = ref('ws://1.92.74.42:81/socket');
const webSocket = ref(null);
const isConnected = ref(false);
const isConnecting = ref(false);
const connectionStatus = ref('disconnected');
const statusText = ref('未连接');
const sessionId = ref('');
const messageLogs = ref([]);

// 格式化时间
const formatTime = () => {
  return new Date().toLocaleTimeString();
};

// 记录日志
const logMessage = (content, type = 'info') => {
  messageLogs.value.push({
    time: formatTime(),
    content,
    type
  });

  // 自动滚动到底部
  nextTick(() => {
    const logContainer = document.querySelector('.message-log');
    if (logContainer) {
      logContainer.scrollTop = logContainer.scrollHeight;
    }
  });
};

// 处理服务器消息
const handleServerMessage = (event) => {
  try {
    const data = JSON.parse(event.data);

    // 检测是否是 sessionId 消息 (根据服务器约定的格式)
    if (data.type === 'session' && data.sessionId) {
      sessionId.value = data.sessionId;
      logMessage(`已获取会话 ID: ${data.sessionId}`, 'success');
      return;
    }

    // 处理普通消息
    logMessage(`收到服务器消息: ${data.content}`, 'message');
  } catch (e) {
    // 处理非 JSON 格式消息
    logMessage(`收到原始消息: ${event.data}`, 'message');
  }
};

// 建立连接
const connect = () => {
  if (isConnected.value || isConnecting.value) return;

  isConnecting.value = true;
  updateStatus('connecting', '连接中...');
  logMessage('尝试建立 WebSocket 连接...');

  try {
    webSocket.value = new WebSocket(wsUrl.value);

    // 连接成功回调
    webSocket.value.onopen = () => {
      isConnected.value = true;
      isConnecting.value = false;
      updateStatus('connected', '已连接');
      logMessage('WebSocket 连接成功');

      // 有些服务器会在连接建立后自动发送 sessionId
      // 这里不需要额外操作，等待服务器推送即可
    };

    // 接收消息回调
    webSocket.value.onmessage = handleServerMessage;

    // 连接关闭回调
    webSocket.value.onclose = (event) => {
      isConnected.value = false;
      isConnecting.value = false;
      sessionId.value = '';

      const reason = event.code === 1000 ? '正常关闭' : `错误码: ${event.code}`;
      updateStatus('disconnected', `已断开 (${reason})`);
      logMessage(`连接已关闭: ${reason}`, 'warning');
    };

    // 错误回调
    webSocket.value.onerror = (error) => {
      isConnecting.value = false;
      updateStatus('error', '连接错误');
      logMessage(`连接错误: ${error.message || '未知错误'}`, 'error');
    };
  } catch (error) {
    isConnecting.value = false;
    updateStatus('error', '连接失败');
    logMessage(`连接失败: ${error.message}`, 'error');
  }
};

// 断开连接
const disconnect = () => {
  if (webSocket.value) {
    webSocket.value.close(1000, '用户主动断开');
    webSocket.value = null;
  }
};

// 切换连接状态
const toggleConnection = () => {
  isConnected.value ? disconnect() : connect();
};

// 更新连接状态显示
const updateStatus = (status, text) => {
  connectionStatus.value = status;
  statusText.value = text;
};

// 组件卸载时清理
onUnmounted(() => {
  disconnect();
});
</script>

<style scoped>
.websocket-session-demo {
  max-width: 800px;
  margin: 20px auto;
  padding: 20px;
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
}

.connection-info {
  margin: 15px 0;
  padding: 15px;
  background: #f9fafb;
  border-radius: 6px;
}

.status {
  padding: 8px 12px;
  border-radius: 4px;
  font-weight: 500;
  margin-bottom: 10px;
}

.status.connected {
  background: #f0fdf4;
  color: #166534;
}

.status.connecting {
  background: #fef3c7;
  color: #92400e;
}

.status.disconnected {
  background: #fef2f2;
  color: #b91c1c;
}

.status.error {
  background: #fee2e2;
  color: #dc2626;
}

.session-id {
  padding: 8px 12px;
  background: #f0f9ff;
  border-radius: 4px;
  font-size: 14px;
}

.session-id code {
  font-family: monospace;
  background: rgba(59, 130, 246, 0.1);
  padding: 2px 6px;
  border-radius: 3px;
  color: #2563eb;
}

.controls {
  display: flex;
  gap: 10px;
  margin: 20px 0;
}

.url-input {
  flex: 1;
}

.message-log {
  margin-top: 20px;
  border: 1px solid #e5e7eb;
  border-radius: 6px;
  overflow: hidden;
}

.message-log h3 {
  margin: 0;
  padding: 12px 15px;
  background: #f5f7fa;
  border-bottom: 1px solid #e5e7eb;
  font-size: 16px;
}

.log-entry {
  padding: 8px 15px;
  border-bottom: 1px solid #f0f0f0;
  font-size: 14px;
  display: flex;
  gap: 10px;
}

.log-entry:last-child {
  border-bottom: none;
}

.log-time {
  color: #9ca3af;
  white-space: nowrap;
}

.log-content {
  flex: 1;
}

.log-content.success {
  color: #15803d;
}

.log-content.warning {
  color: #b45309;
}

.log-content.error {
  color: #dc2626;
}

.log-content.message {
  color: #1e40af;
}
</style>
